package com.reverie.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reverie.common.pojo.CommonPageReq;
import com.reverie.config.CommonException;
import com.reverie.entity.Menu;
import com.reverie.entity.Role;
import com.reverie.entity.RoleMenu;
import com.reverie.entity.User;
import com.reverie.mapper.RoleMapper;
import com.reverie.dto.user.RoleSaveParam;
import com.reverie.service.IMenuService;
import com.reverie.service.IRoleMenuService;
import com.reverie.service.IRoleService;
import com.reverie.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Resource
    private IRoleMenuService roleMenuService;
    @Resource
    private IMenuService menuService;
    @Resource
    private IUserService userService;

    @Override
    public Page<Role> queryPage(CommonPageReq<Role> queryPageParam) {
        Role queryParam = queryPageParam.getQueryParam();
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        if(StringUtils.hasLength(queryParam.getName())){
            wrapper.lambda().like(Role::getName,queryParam.getName());
        }
        if(StringUtils.hasLength(queryParam.getCode())){
            wrapper.lambda().like(Role::getCode,queryParam.getCode());
        }
        User user = userService.getById(StpUtil.getLoginId().toString());
        if (user.getRoleId() != 202401) {
            wrapper.lambda().eq(Role::getCreateUserId,StpUtil.getLoginId().toString());
        }
        Page<Role> page = new Page<>(queryPageParam.getPageNo(),queryPageParam.getPageSize());
        page(page,wrapper);
        buildRecords(page.getRecords());
        return page;
    }

    private void buildRecords(List<Role> records) {
        if(!CollectionUtils.isEmpty(records)){
            List<Menu> menuList = menuService.list();
            Map<Integer,Menu> menuMap = menuList.stream().collect(Collectors.toMap(Menu::getId,m -> m));
            Set<Integer> roleIds = new HashSet<>();
            records.forEach(item -> {
                records.forEach(role -> {
                    roleIds.add(role.getId());
                });
            });

            List<RoleMenu> roleMenuList = roleMenuService.listByRoleIds(roleIds);
            Map<Integer,List<RoleMenu>> roleMenuMap = roleMenuList.stream().collect(Collectors.groupingBy(RoleMenu::getRoleId));
            records.forEach(item -> {
                List<RoleMenu> roleMenus = roleMenuMap.get(item.getId());
//                List<Integer> roleMenues = new ArrayList<>();
//                roleMenus.forEach(roleMenu -> {
//                    Menu menu = menuMap.get(roleMenu.getMenuId());
//                });
                item.setCheckedKeys(roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList()));
            });
        }
    }

    @Override
    public Boolean onSave(RoleSaveParam roleSaveParam) {
        if(CollectionUtils.isEmpty(roleSaveParam.getSelectKeys())){
            throw new CommonException("请先选择权限");
        }
        Role role = new Role();
        BeanUtils.copyProperties(roleSaveParam,role);
        if(roleSaveParam.getId() == null){
            Role roleCode = getByCode(role.getCode());
            if(roleCode != null){
                throw new CommonException("角色编码已存在，请重新输入");
            }
            role.setCreateTime(LocalDateTime.now());
            role.setCreateUserId(Integer.valueOf(StpUtil.getLoginId().toString()));
        }
        saveOrUpdate(role);

        roleMenuService.removeByRoleId(role.getId());

        List<RoleMenu> roleMenuList = new ArrayList<>();
        roleSaveParam.getSelectKeys().forEach(key -> {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setRoleId(role.getId());
            roleMenu.setMenuId(Integer.parseInt(key));
            roleMenuList.add(roleMenu);
        });
        return roleMenuService.saveBatch(roleMenuList);
    }

    private Role getByCode(String code) {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Role::getCode,code);
        return getOne(wrapper);
    }
}
